perm filename A97.TEX[106,PHY] blob
sn#834030 filedate 1987-02-09 generic text, type C, neo UTF8
COMMENT ā VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 \magnification\magstephalf
C00015 ENDMK
Cā;
\magnification\magstephalf
\input macro.tex
\def\today{\ifcase\month\or
January\or February\or March\or April\or May\or June\or
July\or August\or September\or October\or November\or December\fi
\space\number\day, \number\year}
\baselineskip 14pt
\rm
\line{\sevenrm a97.tex[106,phy] \today\hfill}
\font\rmn=cmr9
\bigskip
\line{\bf Printing Geometrical Images.\hfil}
To print characters along a line in the output page within a nested
iteration of the form
\smallskip
{\obeylines\obeyspaces\let =\ \tt
FOR R:= 1 TO RMAX DO
BEGIN
FOR C:= 1 TO CMAX DO
(* write correct character for (R,C)*);
WRITELN
END.
}
\smallskip\noindent
find the equation $f(R,C)=0$ for the line, and use the condition
\smallskip
{\obeylines\obeyspaces\let =\ \tt
IF f(R,C)=0
THEN WRITE('*')
ELSE WRITE(' ')
{\baselineskip10pt
1 2 3 4 5
----------
1| *
2| *
3| *
4| *
5|*
}
IF R+C=6 (* F = R+C - 6 *)
THEN WRITE('*')
ELSE WRITE(' ')
}
\smallskip
To print characters on one side of a line, use the appropriate case of
\smallskip
{\obeylines\obeyspaces\let =\ \tt
IF f(R,C)>0
IF f(R,C)<0
IF f(R,C)>=0
IF f(R,C)<=0
}
\smallskip\noindent
where the latter two are appropriate if the dividing line is itself to be dark.
\smallskip
{\obeylines\obeyspaces\let =\ \tt
{\baselineskip10pt
1 2 3 4 5
----------
1|* * * * *
2|* * * *
3|* * *
4|* *
5|*
}
IF R+C <= 6 THEN ...
{\baselineskip10pt
1 2 3 4 5 6 7
--------------
1|
2|
3|
4|
5|
}
IF SQR(R-7)+SQR(C-8)<=18 THEN ...
}
\smallskip\noindent
Shaded regions defined by several lines can be put together using {\tt AND}
and {\tt OR} on the conditions for the separate lines:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
{\baselineskip10pt
-8 8
-------------------------------
-8| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
8| |
-------------------------------
}
IF (R+C>=0) OR (SQR(R)+SQR(C)<=25) THEN ...
{\baselineskip10pt
-8 8
-------------------------------
-8| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
8| |
-------------------------------
}
IF (R+C>=0) AND (SQR(R)+SQR(C)<=25) THEN ...
}
\smallskip
In the first image, where the line and circle cross, three of the adjacent
regions are shaded, so {\tt OR} is correct. In the second, only one is shaded, so
{\tt AND} is correct.
A common situation has two of the four regions, diagonally opposite, shaded
at a crossing. If the equations of the lines are $f(R,C)=0$ and $g(R,C)=0$,
test the product $f(R,C)*g(R,C)$:
\figbox 2truein:
{\obeylines\obeyspaces\let =\ \tt
R-C=0 R+C-8=0 (R-C)*(R+C-8)>0
}
\smallskip\noindent
If you want the dividing lines to be dark, use {\tt >=} or {\tt <= }:
\smallskip
{\obeylines\obeyspaces\let =\ \tt
program PinWheel(output);
const Size = 10;
var Col, Row : integer;
begin (* PinWheel *)
for Row:= - Size to Size do begin
for Col:= -Size to Size do
if (Col * Row * (Col-Row)*(Col+Row)) >= 0 then write('*')
else write(' ');
writeln;
end;
end. (* PinWheel *)
}
\bigskip
{\baselineskip5pt
\halign{\qquad\qquad\lft{\tt #}\cr
*\phantom{*********}***********\cr
**\phantom{********}********** \cr
***\phantom{*******}********* \cr
****\phantom{******}******** \cr
*****\phantom{*****}******* \cr
******\phantom{****}****** \cr
*******\phantom{***}***** \cr
********\phantom{**}**** \cr
*********\phantom{*}*** \cr
************\cr
*********************\cr
\phantom{*********}************\cr
\phantom{********}***\phantom{*}*********\cr
\phantom{*******}****\phantom{**}********\cr
\phantom{******}*****\phantom{***}*******\cr
\phantom{*****}******\phantom{****}******\cr
\phantom{****}*******\phantom{*****}*****\cr
\phantom{***}********\phantom{******}****\cr
\phantom{**}*********\phantom{*******}***\cr
\phantom{*}**********\phantom{********}**\cr
***********\phantom{*********}*\cr}
}
\figbox 3truein:
{\obeylines\obeyspaces\let =\ \tt
program PinWheel(output)
const Size = 10;
var Col, Row : integer;
begin (* PinWheel *)
for Row:= - Size to Size do begin
for Col:= -Size to Size do
if (Col * Row * (Col-Row)*(Col+Row))) >= 0 then write ('*')
else write(' ');
writeln;
end;
end. (* PinWheel *)
}
\smallskip
In the above image, the oval line f=0 separates the image into an outer part
where the test $g<0$ must be made, and an inner part where h<0 must be tested.
We therefore make the test on~$f$ first.
\smallskip
{\obeylines\obeyspaces\let =\ \tt
IF f<0 THEN
IF h<0 THEN WRITE(' ') ELSE WRITE('*')
ELSE
IF g<0 THEN WRITE(' ') ELSE WRITE('*')
}
\smallskip
Rule of good programming practice: Wherever you can, split a problem into
pieces such that some of the difficult aspects of the problem are restricted
to each piece. In short: {\tt DIVIDA UT IMPERE (DIVIDE AND CONQUER)}.
After having designed a program that prints an image, we decide to overlay
it with a one-inch grid of asterisks. Using the condition
\smallskip
{\obeylines\obeyspaces\let =\ \tt
IF (R MOD 6=0) OR (C MOD 10=0)
THEN WRITE('*')
ELSE whatever we had before
}
\smallskip\noindent
gives priority to the grid, and thereby lays it over the other image.
\figbox 1truein:
To print alternate dark and white diagonal
stripes, each five characters wide, notice
that the sum R+C indicates which diagonal we are on, and diagonals separated
by multiples of ten are the same shade, so we may test {\tt (R+C) MOD 10}.
The correct condition is
\smallskip
{\obeylines\obeyspaces\let =\ \tt
IF (R+C) MOD 10<5
THEN WRITE(' ')
ELSE WRITE('*')
}
\figbox 3truein:
\centerline{The repeated pattern}
\smallskip
{\obeylines\obeyspaces\let =\ \tt
IF (R MOD 6=0) OR (C MOD 10=0)
THEN WRITE('*')
ELSE
IF (R MOD 12-6) * (C MOD 20-10)>0
(*1*)
THEN WRITE('/')
ELSE WRITE(' ')
}
{\rmn
{\narrower\smallskip\noindent
{\bf Drill:} what happens if we insert
{\obeylines\obeyspaces\let =\ \tt
AND (R+C)MOD 3=0,
}
at (*1*)?
\smallskip}
}
\bigskip
\line{\copyright 1984 Robert W. Floyd;
First draft (not published) March 29, 1984\hfil}
%revised: Date; subsequently revised.\hfill}
\bye